package com.android.fragmentdemo.definervlayoutmanager
import android.app.Activity
import android.graphics.PointF
import android.util.Log
import android.view.View
import androidx.recyclerview.widget.RecyclerView
import com.hengfoxwolf.commonbase.base.util.ScreenUtil

class LooperLayoutManager4(space: Int) : RecyclerView.LayoutManager(), RecyclerView.SmoothScroller.ScrollVectorProvider {

    private val mSpace = space
    //private val mActivity = activity

    override fun onAttachedToWindow(view: RecyclerView?) {
        super.onAttachedToWindow(view)
        //禁用动画
        view?.apply {
            itemAnimator = null
        }
        //ScreenUtil.adapterScreen(mActivity, mActivity.resources.displayMetrics.ydpi, false)
    }

    //在某些操作中禁用动画效果
    override fun supportsPredictiveItemAnimations() = false

    override fun onDetachedFromWindow(view: RecyclerView?, recycler: RecyclerView.Recycler?) {
        super.onDetachedFromWindow(view, recycler)
        //ScreenUtil.resetScreen(mActivity)
    }

    override fun generateDefaultLayoutParams(): RecyclerView.LayoutParams {
        return RecyclerView.LayoutParams(
            RecyclerView.LayoutParams.WRAP_CONTENT,
            RecyclerView.LayoutParams.WRAP_CONTENT
        )
    }

    override fun computeScrollVectorForPosition(targetPosition: Int): PointF? {
        return if (childCount == 0) {
            null
        } else {
            val firstChildPos = getPosition(getChildAt(0)!!)
            val direction = if (targetPosition < firstChildPos) -1 else 1
            return PointF(direction.toFloat(), 0F)
        }
    }

    override fun onLayoutChildren(recycler: RecyclerView.Recycler, state: RecyclerView.State) {
        //分离并且回收当前附加的所有View
        detachAndScrapAttachedViews(recycler)
        if (itemCount == 0) {
            return
        }
        //横向绘制子View,则需要知道 X轴的偏移量
        var offsetX = 0
        //绘制并添加view
        for (i in 0 until itemCount) {
            val view = recycler.getViewForPosition(i)
            addView(view)
            measureChildWithMargins(view, 0, 0)
            val viewWidth = getDecoratedMeasuredWidth(view)
            val viewHeight = getDecoratedMeasuredHeight(view)
            layoutDecorated(view, offsetX, 0, offsetX + viewWidth, viewHeight)
            offsetX += viewWidth + mSpace
            //可以适当放宽一些限制，多加载一些view，预防一些未知问题。
            if (offsetX > width /** 5 / 4*/) {
                //Log.d(TAG,"i--${i}")
                break
            }
        }
    }

    //是否可横向滑动
    override fun canScrollHorizontally() = true

    override fun scrollHorizontallyBy(
        dx: Int, recycler: RecyclerView.Recycler, state: RecyclerView.State
    ): Int {
        recycleViews(dx, recycler)
        fill(dx, recycler)
        offsetChildrenHorizontal(dx * -1)
        return dx
    }

    private fun fill(dx: Int, recycler: RecyclerView.Recycler) {
        if (dx > 0) {
            //左滑
            while (true) {
                //得到当前已添加（可见）的最后一个子View
                //Log.d(TAG,"childCount--${childCount}")
                //Log.d(TAG, "lastVisibleView==null")
                val lastVisibleView = getChildAt(childCount - 1) ?: break

                //如果滑动过后，View还是未完全显示出来就 不进行绘制下一个View
                if (lastVisibleView.right - dx > width) break

                //得到View对应的位置
                val layoutPosition = getPosition(lastVisibleView)
                /**
                 * 例如要显示20个View，当前可见的最后一个View就是第20个，那么下一个要显示的就是第一个
                 * 如果当前显示的View不是第20个，那么就显示下一个，如当前显示的是第15个View，那么下一个显示第16个
                 * 注意区分 childCount 与 itemCount
                 */
                val nextView : View = if (layoutPosition == itemCount - 1) {
                    recycler.getViewForPosition(0)
                } else {
                    recycler.getViewForPosition(layoutPosition + 1)
                }
                //Log.d(TAG, "nextView==null")
                addView(nextView)
                measureChildWithMargins(nextView, 0, 0)
                val viewWidth = getDecoratedMeasuredWidth(nextView)
                val viewHeight = getDecoratedMeasuredHeight(nextView)
                val offsetX = lastVisibleView.right + mSpace
                layoutDecorated(nextView, offsetX, 0, offsetX + viewWidth, viewHeight)
            }
        } else {
            //右滑
            while (true) {
                val firstVisibleView = getChildAt(0) ?: break
                if (firstVisibleView.left - dx < 0) break
                val layoutPosition = getPosition(firstVisibleView)
                /**
                 * 如果当前第一个可见View为第0个，则左侧显示第20个View 如果不是，下一个就显示前一个
                 */
                val nextView = if (layoutPosition == 0) {
                    recycler.getViewForPosition(itemCount - 1)
                } else {
                    recycler.getViewForPosition(layoutPosition - 1)
                }
                addView(nextView, 0)
                measureChildWithMargins(nextView, 0, 0)
                val viewWidth = getDecoratedMeasuredWidth(nextView)
                val viewHeight = getDecoratedMeasuredHeight(nextView)
                val offsetX = firstVisibleView.left - mSpace
                layoutDecorated(nextView, offsetX - viewWidth, 0, offsetX, viewHeight)
            }
        }
    }

    private fun recycleViews(dx: Int, recycler: RecyclerView.Recycler) {
        for (i in 0 until itemCount) {
            val childView = getChildAt(i) ?: continue
            if (dx > 0) {
                //左滑
                //移除并回收 原点 左侧的子View
                if (childView.right - dx < 0) {
                    removeAndRecycleViewAt(i, recycler)
                }
            } else {
                //右滑
                //移除并回收 右侧即RecyclerView宽度之以外的子View
                if (childView.left - dx > width) {
                    removeAndRecycleViewAt(i, recycler)
                }
            }
        }
    }

    companion object {
        const val TAG = "LooperLayoutManager4"
    }
}